﻿/*
NTerm: A .NET based terminal abstraction library
Copyright (C) 2011  Bryan Perris

This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;

namespace NTerm
{
    /// <summary>
    /// Internal class
    /// </summary>
    internal sealed class DefaultHostHandler : HostHandler
    {
        public override void Initialize()
        {
            Console.BackgroundColor = NTerminal.BackgroundColor;
			Console.ForegroundColor = NTerminal.ForegroundColor;
			Console.Clear();
        }

        public override void Dispose()
        {
            Console.ResetColor();
            Console.Clear();
            Console.CursorLeft = 0;
            Console.CursorTop = 0;
        }

        public override void UpdateCursor(int row, int col)
        {
            Console.SetCursorPosition(col, row);
        }

        public override int GetBufferWidth()
        {
			MonoBufferSizeTrick();
            return Console.BufferWidth;
        }

        public override int GetBufferHeight()
        {
			MonoBufferSizeTrick();
            return Console.BufferHeight;
        }

        public override void AppendOutput(CharacterCell[] cells)
        {
            foreach (CharacterCell cell in cells)
            {
                Console.BackgroundColor = cell.BackgroundColor;
                Console.ForegroundColor = cell.BoregroundColor;
                Console.Write(cell.Character);
            }
        }

        public override void RefreshOutput(CharacterCell[,] cells)
        {
            Console.BackgroundColor = NTerminal.BackgroundColor;
            Console.ForegroundColor = NTerminal.ForegroundColor;
            Console.Clear();
            Console.SetCursorPosition(0, 0);
			int r = 0; // This is needed for mono, it ensures that data is not all written to the same line (some odd bug)

            for (int row = 0; row < cells.GetLength(0); row++)
            {
                for (int col = 0; col < cells.GetLength(1); col++)
                {
                    // Prevents host from scrolling again
                    if ((row == cells.GetLength(0) - 1) && (col == cells.GetLength(1) - 1))
                        return;

                    Console.BackgroundColor = cells[row, col].BackgroundColor;
                    Console.ForegroundColor = cells[row, col].BoregroundColor;
                    Console.Write(cells[row, col].Character);
                }
				
				Console.CursorTop = ++r;
            }
        }

        public override string ReadLine()
        {
            return Console.ReadLine();
        }

        public override ConsoleKeyInfo ReadKey(bool intercept)
        {
            return Console.ReadKey(intercept);
        }

        public override int Read()
        {
            return Console.Read();
        }
		
		public override void SetBufferSize(int width, int height)
		{
			Console.SetBufferSize(width, height);
		}
		
		private void MonoBufferSizeTrick()
		{
            // This method is needed when running on Mono, calling this property causes Mono's ConsoleDriver
            // for terminals that support terminfo, to update the bufferSize when checking the Window Dimensions

			if (Console.WindowWidth > 0)
				return;
		}

        public override void ClearScreen()
        {
            Console.Clear();
        }

        public override void ResetColor(ConsoleColor backgroundColor, ConsoleColor foregroundColor)
        {
            Console.BackgroundColor = backgroundColor;
            Console.ForegroundColor = foregroundColor;
        }

        public override TextReader In
        {
            get
            {
                return Console.In;
            }
            set
            {
                Console.SetIn(value);
            }
        }
    }
}
